L.Control.Basemaps = L.Control.extend({
    _map: null,
    includes: L.Evented ? L.Evented.prototype : L.Mixin.Event,
    options: {
        position: "bottomright",
        layers: []
    },
    basemap: null,
    onAdd: function (map) {
        this._map = map;
        var container = L.DomUtil.create("div", "basemaps leaflet-control closed");

        // disable events
        L.DomEvent.disableClickPropagation(container);
        if (!L.Browser.touch) {
            L.DomEvent.disableScrollPropagation(container);
        }

        this.options.basemaps.forEach(function (basemap, i) {
            var basemapClass = "basemap";

            if (i === 0) {
                this.basemap = basemap;
                map.options.crs = basemap.options.crs ? basemap.options.crs : L.CRS.EPSG3857;
                basemap.addTo(map);
                map.setView(map.options.center, map.options.zoom);
                basemapClass += " basemap-active";
                if (this.options.basemaps.length > 2) {
                    basemapClass += " alt";
                }
            } else if (i === 1 && this.options.basemaps.length == 2) {
                basemapClass += " alt";
            }
            var url;
            if (basemap.options.iconURL) {
                url = basemap.options.iconURL;
            }
            else {
                url = "./images/basemap.png";
            }

            var basemapNode = L.DomUtil.create("div", basemapClass, container);
            var imgNode = L.DomUtil.create("img", null, basemapNode);
            imgNode.src = url;
            if (basemap.options && basemap.options.label) {
                imgNode.title = basemap.options.label;
            }
            var spanNode = L.DomUtil.create("span", null, basemapNode);
            spanNode.innerHTML = basemap.options.label;

            L.DomEvent.on(
                basemapNode,
                "click",
                function () {
                    //if different, remove previous basemap, and add new one
                    if (basemap != this.basemap) {
                        if (this.basemap.options.crs != basemap.options.crs) {
                            var bounds = map.getBounds();
                            var center = map.getCenter();
                            var zoom = map.getZoom();
                            this.basemap.removeFrom(map);
                            map.options.crs = basemap.options.crs;
                            basemap.addTo(map);
                            map.fitBounds(bounds);
                            map.setZoom(zoom);
                        }
                        else {
                            this.basemap.removeFrom(map);
                            basemap.addTo(map);
                        }

                        map.fire("baselayerchange", basemap);
                        this.basemap = basemap;

                        L.DomUtil.removeClass(container.getElementsByClassName("basemap basemap-active")[0], "basemap-active");
                        L.DomUtil.addClass(basemapNode, "basemap-active");

                        // 只有两种底图时直接切换，不飘出来
                        // if (this.options.basemaps.length == 2) {
                        //     var altIdx = (i + 1) % this.options.basemaps.length;
                        //     L.DomUtil.removeClass(container.getElementsByClassName("basemap alt")[0], "alt");
                        //     L.DomUtil.addClass(container.getElementsByClassName("basemap")[altIdx], "alt");
                        // }else
                        if (this.options.basemaps.length >= 2) {
                            var altIdx = (i + 0) % this.options.basemaps.length;
                            L.DomUtil.removeClass(container.getElementsByClassName("basemap alt")[0], "alt");
                            L.DomUtil.addClass(container.getElementsByClassName("basemap")[altIdx], "alt");
                        }
                    }
                },
                this
            );
        }, this);

        if (this.options.basemaps.length >= 2) {
            L.DomEvent.on(
                container,
                "mouseenter",
                function () {
                    L.DomUtil.removeClass(container, "closed");
                },
                this
            );

            L.DomEvent.on(
                container,
                "mouseleave",
                function () {
                    L.DomUtil.addClass(container, "closed");
                },
                this
            );
        }

        this._container = container;
        return this._container;
    }
});

L.control.basemaps = function (options) {
    return new L.Control.Basemaps(options);
};